package mbsl.system;

import static java.util.logging.Level.*;

import java.util.logging.ConsoleHandler;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.LogRecord;

/**
 * A simple logger which routes messages to java's own Logger.  The point of this class is to provide
 * log4j-style message types with a modern logger.
 * <p>
 * Supported types:<br>
 * info: A purely informational message, like "Starting UI" or "Shutting down".<br>
 * debug: A message intended to be helpful in debugging, like "Refreshed with arguments [where cake like 'a lie']".<br>
 * warning: A message to inform that something didn't go as expected, but the program can handle it, like "Couldn't load extension Cake".<br>
 * fatal: A message to inform that something didn't go as expected, and the program can't move on, like "Database not found".<br>
 * error: This simply routes to warning.
 * <p>
 * The graining order is as follows:<br>
 * debug < info < warning/error < fatal
 */
public class Logger {
	private java.util.logging.Logger mLogger;

	public Logger(Class<?> pClass) {
		mLogger = java.util.logging.Logger.getLogger(pClass.getCanonicalName());
		
		mLogger.setUseParentHandlers(false);
		mLogger.addHandler(SIMPLE);
	}
	/** 
	 * Logs an info message
	 * @param pMessage The formatable message string.
	 * @param pArguments The objects used to format this message. See {@link java.lang.String#format}. 
	 */
	public void info(String pMessage, Object ... pArguments) {
		mLogger.info(String.format(pMessage, pArguments));
	}
	/** 
	 * Logs a debug message 
	 * @param pMessage The formatable message string.
	 * @param pArguments The objects used to format this message. See {@link java.lang.String#format}. 
	 */
	public void debug(String pMessage, Object ... pArguments) {
		mLogger.fine(String.format(pMessage, pArguments));
	}
	/** 
	 * Logs a warning message
	 * @see #warning(String, Throwable, Object...)
	 * @param pMessage The formatable message string.
	 * @param pArguments The objects used to format this message. See {@link java.lang.String#format}. 
	 */
	public void warning(String pMessage, Object ... pArguments) {
		mLogger.warning(String.format(pMessage, pArguments));
	}
	/** 
	 * Logs a warning message
	 * @see #warning(String, Object...)
	 * @param pMessage The formatable message string.
	 * @param pException The Throwable which caused this message.
	 * @param pArguments The objects used to format this message. See {@link java.lang.String#format}. 
	 */
	public void warning(String pMessage, Throwable pException, Object ... pArguments) {
		mLogger.log(WARNING, String.format(pMessage, pArguments), pException);
	}
	/** 
	 * Logs a message of type fatal
	 * @see #fatal(String, Throwable, Object...)
	 * @param pMessage The formatable message string.
	 * @param pArguments The objects used to format this message. See {@link java.lang.String#format}. 
	 */
	public void fatal(String pMessage, Object ... pArguments) {
		mLogger.severe(String.format(pMessage, pArguments));
	}
	/** 
	 * Logs a message of type fatal
	 * @see #fatal(String, Object...)
	 * @param pMessage The formatable message string.
	 * @param pException The Throwable which caused this message.
	 * @param pArguments The objects used to format this message. See {@link java.lang.String#format}. 
	 */
	public void fatal(String pMessage, Throwable pException, Object ... pArguments) {
		mLogger.log(SEVERE, String.format(pMessage, pArguments), pException);
	}
	/**
	 * A log handler with no filtering and a simplistic type of output.  Output style is <b>TYPE: Message</b>.
	 */
	public static Handler SIMPLE;
	
	static {
		SIMPLE = new ConsoleHandler();

		SIMPLE.setLevel(FINEST);
		SIMPLE.setFormatter(new Formatter() {
			public String format(LogRecord pRecord) {
				return String.format("%1$-7s : %2$s\n", pRecord.getLevel(), pRecord.getMessage());
			}
		});
	}
}